/**
 * @file DHT.c
 * @brief       DHT11文件
 * @version     0.1
 * @date        2023
 * 
 * @copyright   Copyright © 2025 by JinChengLong 
 * 
 * All rights reserved.
 * Unauthorized copying, reproduction, or redistribution of this file via any medium is strictly prohibited.  
 * Proprietary and confidential.
 *   
 */
#include "DHT.h"

uint8_t H11,h11,T11,t11,S11;


/**
 * @brief DHT11初始化
 * 
 */
void DHT_init(void)//打开时钟
{
	GPIO_InitTypeDef GPIO_InitStructure;	
	RCC_APB2PeriphClockCmd(DHT11_CLK, ENABLE); 
														   
	GPIO_InitStructure.GPIO_Pin = DHT11_PIN;	
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;  
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; 
	GPIO_Init(DHT11_PORT, &GPIO_InitStructure);		  

	GPIO_SetBits(DHT11_PORT, DHT11_PIN);	
	
}

/**
 * @brief 设置上拉输入
 * 
 */
 void DHT_IPU(void)//上拉输入
{
	
	GPIO_InitTypeDef GPIO_InitStructure;
	GPIO_InitStructure.GPIO_Pin = DHT11_PIN;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU ;    
	GPIO_Init(DHT11_PORT, &GPIO_InitStructure);
	
}


/**
 * @brief 设置推完输出
 * 
 */
 void DHT_Out_PP(void)//推挽输出
{
	
	GPIO_InitTypeDef GPIO_InitStructure;
	
	GPIO_InitStructure.GPIO_Pin = DHT11_PIN;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP ;    
	GPIO_Init(DHT11_PORT, &GPIO_InitStructure);
	GPIO_ResetBits(DHT11_PORT, DHT11_PIN);
}



/**
 * @brief 读数据
 * 
 * @return uint8_t 成功0
 */
uint8_t DHT_R(void)//读取数据
{
	uint8_t i,M=0;
	
	for(i=0;i<8;i++)    
	{	   
		while(GPIO_ReadInputDataBit(DHT11_PORT,DHT11_PIN)==Bit_RESET); //等待低电平50us结束 
		Delay_us(40);   //多延迟40us判断数据
		
		//26到28us高电平为0
		//70us高电平为1
		   	  

		if(GPIO_ReadInputDataBit(DHT11_PORT,DHT11_PIN)==Bit_SET) //高电平70us  
		{
			while(GPIO_ReadInputDataBit(DHT11_PORT,DHT11_PIN)==1);  
			M|=(uint8_t)(0x01<<(7-i));//存入数据 //将1左移7-i位 强制无符号数 存入
		}
		else//高电平26到28us	
		{			   
			M&=(uint8_t)~(0x01<<(7-i));//存入数据//将1左移7-i位 取反 强制无符号数 将取反的其他位置0  存入
		}
	}
	
	return M;
	
	
}




/**
 * @brief 读DHT11数据
 * 
 * @return uint8_t 成功0，失败-1
 */
uint8_t Read_DHT11(void)
{  	
	DHT_init();
		
	DHT_Out_PP();   
	
	GPIO_ResetBits(DHT11_PORT,DHT11_PIN); // 推挽输出拉低18ms 
	
	Delay_ms(18);      

	GPIO_SetBits(DHT11_PORT,DHT11_PIN);  //拉高电平保持20us到40us 
	
	Delay_us(30);        

	DHT_IPU();  //上拉输入
   
	if(GPIO_ReadInputDataBit(DHT11_PORT ,DHT11_PIN)==0)  
	{  
		
		while(GPIO_ReadInputDataBit(DHT11_PORT,DHT11_PIN)==0);  //DHT11响应80us的低电平信号
		while(GPIO_ReadInputDataBit(DHT11_PORT,DHT11_PIN)==1);   //DHT11响应80us的高电平信号 

		
		H11= DHT_R();
		h11= DHT_R();
		T11= DHT_R();
		t11= DHT_R();
		S11= DHT_R();

		DHT_Out_PP();   //推挽输出 
		GPIO_SetBits(DHT11_PORT,DHT11_PIN);//拉高电平

		
		if(S11==H11+h11+T11+t11)//校验是否数据正确
		{
			return 1;
		}
		else 
		{
			return 0;
		}
	}
	else
	{		
		return 0;
	}   
}









